﻿using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System.Collections.Generic;

namespace HexTileBoard
{
    public class Tile : SceneObject
    {
        public int IndexInBoard;
        public int file;              // 0-based file, linear up and down in X-axis
        public int rank;              // 0-based rank, v-shaped horizontally
        public Tile[] Neighbors = new Tile[6] { null, null, null, null, null, null };

        public HexTileBase TileBase;
        public HexTileNaturalModifier NaturalModifier;
        public HexTileManMadeModifier ManMadeModifier;
        public HexTileResource ResourceModifier;

        public Tile(int _IndexInBoard, int _file, int _rank, Model p_Model, Texture2D[] p_ModelTextures, Vector3 p_Position, Vector3 p_Rotation, float p_Scale)
            : base(p_Model, p_ModelTextures, p_Position, p_Rotation, p_Scale)
        {
            IndexInBoard = _IndexInBoard;
            file = _file;
            rank = _rank;
        }
    }

    public class TileSimple
    {
        public int IndexInBoard;
        public int file;              // 0-based file, linear up and down in X-axis
        public int rank;              // 0-based rank, v-shaped horizontally
        public TileSimple[] Neighbors = new TileSimple[6] { null, null, null, null, null, null };

        // Influence values
        public PlayerColor tileOwner = PlayerColor.None;
        public PlayerColor previousOwner = PlayerColor.None;
        public int value = 0;
        public int previousValue = 0;
        // track the temporary colors when trying to determine final owner of tile
        public Dictionary<PlayerColor, int> color = new Dictionary<PlayerColor, int>();


        // Tile types and modifiers
        public HexTileBase TileBase;
        public HexTileNaturalModifier NaturalModifier;
        public HexTileNaturalModifier PreviousNaturalModifier = HexTileNaturalModifier.None;
        public HexTileManMadeModifier ManMadeModifier;
        public HexTileManMadeModifier PreviousManMadeModifier = HexTileManMadeModifier.None;
        public HexTileResource ResourceModifier;

        public Matrix naturalMatrix = Matrix.Identity;    // natural modifiers are randomly rotated
        public float naturalRotationAmount = 0.0f;
        public PlayerColor buildingOwner = PlayerColor.None;// used to track who owns the manmade modifier on the tile so that it can never lose all influence

        // Units, as tile variables for simplicity's sake
        public TileUnit unit = TileUnit.None;
        public PlayerColor unitColor = PlayerColor.None;

        // Model drawing
        private Vector3 position = Vector3.Zero;
        private Vector3 rotation = Vector3.Zero;
        private float scale = 1.0f;
        private Matrix modelMatrix = Matrix.Identity;
        private BoundingSphere boundingSphere;

        // Where the tile will end up when done elevating
        public Vector3 DesiredPosition = Vector3.Zero;

        public Vector3 Position
        {
            get { return position; }
            set
            {
                position = value;
                modelMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
                boundingSphere.Center = position;
            }
        }
        // For changing only the Y value
        public float PositionY
        {
            get { return position.Y; }
            set
            {
                position.Y = value;
                modelMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
                boundingSphere.Center = position;
            }
        }
        public Vector3 Rotation
        {
            get { return rotation; }
            set
            {
                rotation = value;
                modelMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
            }
        }
        public float Scale
        {
            get { return scale; }
            set
            {
                scale = value;
                modelMatrix = Matrix.CreateScale(scale) * Matrix.CreateRotationX(rotation.X) * Matrix.CreateRotationY(rotation.Y) * Matrix.CreateRotationZ(rotation.Z) * Matrix.CreateTranslation(position);
                boundingSphere.Radius *= scale;
            }
        }
        public Matrix ModelMatrix
        {
            get { return modelMatrix; }
        }
        public BoundingSphere BS
        {
            get { return boundingSphere; }
        }

        public TileSimple(int _IndexInBoard, int _file, int _rank, Vector3 _Position, Vector3 _Rotation, float _Scale)
        {
            TileBase = HexTileBase.Grass;
            NaturalModifier = HexTileNaturalModifier.None;
            ManMadeModifier = HexTileManMadeModifier.None;
            ResourceModifier = HexTileResource.None;

            tileOwner = PlayerColor.None;
            buildingOwner = PlayerColor.None;

            color.Add(PlayerColor.Blue, 0);
            color.Add(PlayerColor.Red, 0);
            color.Add(PlayerColor.Green, 0);
            color.Add(PlayerColor.Yellow, 0);

            IndexInBoard = _IndexInBoard;
            file = _file;
            rank = _rank;

            boundingSphere = new BoundingSphere(Vector3.Zero, BoardVariables.tileModelDepth / BoardVariables.boundingScale);

            this.position = _Position;
            this.DesiredPosition = _Position;
            this.rotation = _Rotation;
            this.scale = _Scale;
            this.modelMatrix = Matrix.CreateScale(this.Scale) * Matrix.CreateRotationX(this.Rotation.X) * Matrix.CreateRotationY(this.Rotation.Y) * Matrix.CreateRotationZ(this.Rotation.Z) * Matrix.CreateTranslation(this.Position);
        }
    }
}
